package sspatcher;

import sspatcher.entity.PatchRuleEntity;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ASMHelper {
    public static byte[] applyPatchToBytecode(byte[] bytecode, List<PatchRuleEntity> rules) {
        int idx = 0;
        List<byte[]> binaryAssembly = new ArrayList<>();
        for (PatchRuleEntity rule : rules) {
            if (idx > rule.getIndex()) {
                throw new RuntimeException(String.format("conflict patch detected, or patch order is incorrect. idx(0x%x) > rule$index(0x%x)", idx, rule.getIndex()));
            }
            binaryAssembly.add(Arrays.copyOfRange(bytecode, idx, rule.getIndex()));
            switch (rule.getTypeEnum()) {
                case INSERT:
                    binaryAssembly.add(Utilities.getBytesFromSpacedHexText(rule.getData()));
                    idx = rule.getIndex();
                    break;
                case OVERRIDE:
                    byte[] decoded = Utilities.getBytesFromSpacedHexText(rule.getData());
                    binaryAssembly.add(decoded);
                    idx = rule.getIndex() + decoded.length;
                    break;
                case REMOVE:
                    idx = rule.getIndex() + Utilities.parseIntAutoHex(rule.getData());
                    break;
                default:
                    throw new RuntimeException("Invalid enum: " + rule.getTypeEnum().toString());
            }
        }
        if (idx < bytecode.length) {
            binaryAssembly.add(Arrays.copyOfRange(bytecode, idx, bytecode.length));
        }
        return Utilities.concatenateByteArrays(binaryAssembly);
    }
}
